#!/usr/bin/env node

/**
 * CodeMind MCP Server
 * @version 0.4.2
 * @description A stable MCP server for GitCode and Mindmap generation, refactored to use McpServer.
 */

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import { gitcodeRequest } from "./gitcode.js";
import { generateReadmeMindmap } from "./mindmap.js";

const SERVER_VERSION = '3.0.0';

// Define Zod schemas for tool inputs for robust validation
const GitcodeArgsSchema = z.object({
  baseUrl: z.string().optional(),
  token: z.string(),
  method: z.enum(["GET", "POST", "PUT", "PATCH", "DELETE"]),
  path: z.string(),
  query: z.record(z.any()).optional(),
  body: z.record(z.any()).optional(),
  headers: z.record(z.string()).optional(),
});

const ReadmeMindmapArgsSchema = z.object({
  prompt: z.string().optional(),
});

const GitRepoArgsSchema = z.object({
  repoUrl: z.string(),
  targetDir: z.string().optional(),
});

class CodeMindMCPServer {
  private server: McpServer;

  constructor() {
    console.log(`[CodeMind] Initializing server v${SERVER_VERSION}...`);
    this.server = new McpServer({
      name: '@lucianaib/codemind-mcp',
      version: SERVER_VERSION,
      // CRITICAL: This capability flag is required by the SDK version to enable tools.
      capabilities: {
        tools: true,
      },
    });
    this.registerTools();
  }

  private registerTools(): void {
    // Tool 1: gitcode_request
    this.server.registerTool(
      "gitcode_request",
      {
        description: "调用GitCode API的通用工具",
        inputSchema: GitcodeArgsSchema.shape,
      },
      async (args: z.infer<typeof GitcodeArgsSchema>) => {
        try {
          console.log(`[CodeMind] 调用工具 'gitcode_request' 处理路径: ${args.path}`);
          
          // 检查路径格式，确保以/开头
          let path = args.path;
          if (!path.startsWith('/')) {
            path = '/' + path;
          }
          
          // 针对常见的仓库访问错误提供更好的错误提示
          if (path.includes('/repos/') && !path.includes('?')) {
            // 这是一个仓库查询，检查可能的错误
            const pathParts = path.split('/');
            if (pathParts.length >= 4 && pathParts[2] === 'repos') {
              const owner = pathParts[3];
              const repo = pathParts[4];
              console.log(`[CodeMind] 访问仓库: ${owner}/${repo}`);
            }
          }
          
          const result = await gitcodeRequest({
            ...args,
            path: path
          });
          
          // 如果是404错误，提供更有用的错误信息
          if (result.status === 404) {
            return {
              isError: true,
              content: [{ type: "text", text: `GitCode API 返回404错误：仓库不存在或路径不正确\n\n请检查：\n1. 仓库URL是否正确\n2. 仓库名称是否拼写正确\n3. 是否有访问权限\n\n请求URL: ${result.url}\n错误详情: ${JSON.stringify(result.data, null, 2)}` }],
            };
          }
          
          return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
        } catch (error) {
          console.error(`[CodeMind] 执行 'gitcode_request' 时出错:`, error);
          return {
            isError: true,
            content: [{ type: "text", text: `GitCode 请求失败: ${error instanceof Error ? error.message : String(error)}` }],
          };
        }
      }
    );

    // Tool 2: mindmap
    this.server.registerTool(
      "mindmap",
      {
        description: "对当前项目的README.md文件制作思维导图",
        inputSchema: ReadmeMindmapArgsSchema.shape,
      },
      async (args: z.infer<typeof ReadmeMindmapArgsSchema>) => {
        try {
          console.log(`[CodeMind] 调用工具 'mindmap' 生成README思维导图`);
          const result = await generateReadmeMindmap();
          const text = `思维导图链接: ${result.mindmapUrl}\n\n${result.message}`;
          return { content: [{ type: "text", text }] };
        } catch (error) {
          console.error(`[CodeMind] 执行 'mindmap' 时出错:`, error);
          return {
            isError: true,
            content: [{ type: "text", text: `README思维导图生成失败: ${error instanceof Error ? error.message : String(error)}` }],
          };
        }
      }
    );

    // Tool 3: git_project_info
    this.server.registerTool(
      "git_project_info",
      {
        description: "获取Git项目信息，支持不同Git平台",
        inputSchema: GitRepoArgsSchema.shape,
      },
      async (args: z.infer<typeof GitRepoArgsSchema>) => {
        try {
          console.log(`[CodeMind] 调用工具 'git_project_info' 获取项目信息: ${args.repoUrl}`);
          
          // 解析仓库URL，提取平台、所有者和仓库名
          let platform = "";
          let owner = "";
          let repo = "";
          let apiUrl = "";
          
          try {
            // 尝试匹配不同的Git平台URL格式
            const githubMatch = args.repoUrl.match(/https?:\/\/(?:www\.)?github\.com\/([^\/]+)\/([^\/\.]+)/);
            const gitcodeMatch = args.repoUrl.match(/https?:\/\/(?:www\.)?([^\/]+)\/([^\/]+)\/([^\/\.]+)/);
            
            if (githubMatch) {
              [, owner, repo] = githubMatch;
              platform = "GitHub";
              apiUrl = `https://api.github.com/repos/${owner}/${repo}`;
            } else if (gitcodeMatch) {
              let domain = "";
              [, domain, owner, repo] = gitcodeMatch;
              platform = domain;
              if (domain === "gitcode.net") {
                apiUrl = `https://gitcode.net/api/v5/repos/${owner}/${repo}`;
              } else {
                apiUrl = `https://gitcode.com/api/v5/repos/${owner}/${repo}`;
              }
            } else {
              throw new Error("不支持的Git平台URL格式");
            }
            
            // 尝试获取仓库信息
            let result;
            if (platform === "GitHub") {
              // GitHub API需要不同的处理方式
              const response = await fetch(apiUrl);
              const data = await response.json();
              result = {
                status: response.status,
                ok: response.ok,
                url: apiUrl,
                data
              };
            } else {
              // GitCode平台使用gitcodeRequest
              result = await gitcodeRequest({
                token: "", // 公开仓库不需要token
                method: "GET",
                path: `/repos/${owner}/${repo}`,
                baseUrl: apiUrl.includes('/api/v5') ? apiUrl.replace(/\/repos\/[^\/]+\/[^\/]+$/, '') : apiUrl
              });
            }
            
            if (result.status === 404) {
              // 尝试直接使用URL作为API路径
              const apiPath = `/repos/${owner}/${repo}`;
              let baseApiUrl = "";
              
              if (platform === "GitHub") {
                baseApiUrl = "https://api.github.com";
              } else if (platform.includes("gitcode")) {
                baseApiUrl = `https://${platform}/api/v5`;
              } else {
                baseApiUrl = apiUrl.replace(/\/repos\/[^\/]+\/[^\/]+$/, "");
              }
              
              const retryResult = await gitcodeRequest({
                token: "",
                method: "GET",
                path: apiPath,
                baseUrl: baseApiUrl
              });
              
              if (retryResult.ok) {
                return { content: [{ type: "text", text: `平台: ${platform}\n所有者: ${owner}\n仓库名: ${repo}\n仓库信息:\n${JSON.stringify(retryResult.data, null, 2)}` }] };
              } else {
                throw new Error(`仓库不存在或无法访问: ${args.repoUrl}`);
              }
            }
            
            return { content: [{ type: "text", text: `平台: ${platform}\n所有者: ${owner}\n仓库名: ${repo}\n仓库信息:\n${JSON.stringify(result.data, null, 2)}` }] };
          } catch (parseError) {
            throw new Error(`无法解析仓库URL: ${args.repoUrl}\n错误: ${parseError instanceof Error ? parseError.message : String(parseError)}`);
          }
        } catch (error) {
          console.error(`[CodeMind] 执行 'git_project_info' 时出错:`, error);
          return {
            isError: true,
            content: [{ type: "text", text: `获取项目信息失败: ${error instanceof Error ? error.message : String(error)}` }],
          };
        }
      }
    );
  }

  public async run(): Promise<void> {
    const transport = new StdioServerTransport();
    process.on('SIGINT', () => {
      console.log('[CodeMind] SIGINT received, shutting down.');
      this.server.close();
      process.exit(0);
    });
    await this.server.connect(transport);
    console.error(`CodeMind MCP Server v${SERVER_VERSION} is running successfully.`);
  }
}

// Main execution block
try {
  const server = new CodeMindMCPServer();
  server.run();
} catch (error) {
  console.error('Failed to initialize or run the server:', error);
  process.exit(1);
}